'use strict';

import React, { Component } from 'react';
import {
    TextInput,
    View,
    Image,
    StyleSheet,
    TouchableHighlight,
    Platform,
    Keyboard,
    Dimensions
} from 'react-native';

import PropTypes from "prop-types";
import enLocale from './locale/en_US';
import zhLocale from './locale/zh_CN';
import Color from "../../config/theme/standard/color"
import FontSize from "../../config/theme/standard/fonts"
import Label from '../label';
import Calculate from '../../config/calculate';
import check from '../../config/validator/check';


export default class TextField extends Component {

    constructor(props) {
        super(props);
        this.locale = this.props.locale == "zh" ? zhLocale:enLocale;
        this.placeholder = this.props.placeholder ? this.props.placeholder : this.locale.placeholder;
        this.textInputRefer = null;

        this.state = {
            prevPropsDefaultValue: props.defaultValue ? props.defaultValue : '',
            showClear: false,
            text: props.defaultValue ? props.defaultValue : '',
            showErrorInfo: this.props.showErrorInfo,
            errorInfo: this.props.errorInfo,
            isWideScreen: false // 鸿蒙适配是否宽屏
        };
    }
    componentDidMount() {
        // 适配鸿蒙折叠屏动态更新组件
        Dimensions.addEventListener('change', () => {
            const screenWidth = Dimensions.get('window').width;
            this.setState({
                isWideScreen: screenWidth > 500 && screenWidth < 800
            })
        })
    }
    _onChange(text) {
        let textTmp = text;
        if(this.props.calculateStyle === 'normal'){
            if(textTmp.length > this.props.maxLength) {
                textTmp = Calculate.sliceContent(text, this.props.maxLength);
            }
        }
        //rn-web情况下，键盘类型为numeric时maxleng属性无效，需手动截取字符串长度
        if(Platform.OS === 'web' && this.props.keyboardType === 'numeric'){
            if(textTmp.length > this.props.maxLength) {
                textTmp = textTmp.slice(0, this.props.maxLength);
            }
        }
        this.setState({
           text:textTmp
        });
        if(typeof(this.props.onChangeText) === 'function'){
            this.props.onChangeText(textTmp);
        }
    }

    _titleIconClick(){
        if(typeof this.props.titleIconFunc == 'function'){
            this.props.titleIconFunc();
        }
    }

    _leftItemClick(){
        if(this.props.editable){
            this.textInputRefer.focus();
        }else{
            return;
        }
    }

    _onBlur(){
        let checkResult;
        if(this.props.checker) {
            checkResult = check(this.props.configData, this.props.checker, this.state.text, this.props.checkerErrMsg, this.props.maxLength);
            if(checkResult.result) {
                this.setState({
                    showErrorInfo: false
                });
            }else {
                this.setState({
                    showErrorInfo: true,
                    errorInfo: checkResult.message,
                });
            }
        }
        this.setState({
            showClear:false,
        });

        if(Platform.OS == "web"){
            this.setState({
                text:this.state.text.replace(/\u2006/g,'')
            },()=>{
                Keyboard.dismiss()
            })
        }



        if(typeof(this.props.onBlur) === 'function'){
            if(this.props.checker) {
                this.props.onBlur(this.state.text, checkResult);
            }else {
                this.props.onBlur(this.state.text);                
            }
        }
    }

    _onFocus(){
        this.setState({
            showClear:true
        });
        if(typeof(this.props.onFocus) === 'function'){
            this.props.onFocus();
        }
    }

    _onEndEditing(){
        if(typeof(this.props.onEndEditing) === 'function'){
            this.props.onEndEditing(this.state.text);
        }
    }

    _onSubmitEditing(){
        if(typeof(this.props.onSubmitEditing) === 'function'){
            this.props.onSubmitEditing(this.state.text);
        }
    }

    _iconFunc() {
        if (typeof this.props.rightFunc == 'function') {
            this.props.rightFunc();
        }
    }

    _iconFunc2() {
        if (typeof this.props.rightFunc2 == 'function') {
            this.props.rightFunc2();
        }
    }

    static getDerivedStateFromProps(nextProps, prevState) {
        let infoFlag = false;
        let valueFlag = false;
        if ('showErrorInfo' in nextProps && 'errorInfo' in nextProps ) {
            infoFlag = true;
        }
        if (('defaultValue' in nextProps) && (nextProps.defaultValue !== prevState.prevPropsDefaultValue)) {
            valueFlag = true;
        }
    
        if(infoFlag && valueFlag){
            return {
                showErrorInfo:nextProps.showErrorInfo,
                errorInfo:nextProps.errorInfo,
                prevPropsDefaultValue: nextProps.defaultValue,
                text: nextProps.defaultValue
            };
        }else{
            if(infoFlag){
                return {
                    showErrorInfo:nextProps.showErrorInfo,
                    errorInfo:nextProps.errorInfo
                };
            }else if(valueFlag){
                return {
                    prevPropsDefaultValue: nextProps.defaultValue,
                    text: nextProps.defaultValue
                };
            }
        }
        return null;
    }

    render() {
        const {
            title,
            leftIcon,
            showClearIcon,
            textInputStyle,
            editable,
            maxLength,
            maxTitleLength,
            textAlign,
            rightImg,
            isMerge,
            hasTopBorder,
            keyboardType,
            titleWidth,
            secureTextEntry,
            titleIcon,
            isLimitTitleWidth,
            isRequired,
            selectionColor,
            numberOfLines,
            titleStyle,
            errorInfoStyles,
            type,
            isShowBorder
        } = this.props;
        const width = this.props.width ? this.props.width : Dimensions.get('window').width;
        const iconStyles = [styles.icon];
        const imageStyles = [styles.image];
        const clearImageStyles = [styles.clearImage]
        const inputStyles = [styles.input];
        const inputContainerStyles = [styles.inputContainer];
        const imageContainerStyles = [styles.imageContainer, Platform.OS == 'harmony' &&{ zIndex:1 }];
        const dividerStyles= [styles.divider];
        const containerStyles = [styles.container];
        const doubleContainerStyles = [styles.doubleContainer];
        const messageContainerStyles = [styles.messageContainer];
        const titleStyles = [styles.title];
        const starImageStyle = [styles.starImage];

        let maxTitleNum = null;
        let leftElement = null;
        let clearIconElement = null;
        let img1 = null;
        let img2 = null;
        let errorItem = null;

        if(width){
            containerStyles.push({width:width})
        }

        if(titleWidth){
            messageContainerStyles.push({width:titleWidth});
        }
        if(type == 'double'){
            messageContainerStyles.push({width: width-26});
        }

        if(maxTitleLength < 0){
            maxTitleNum = 5;
        }else if(maxTitleLength > 7){
            maxTitleNum = 7;
        }else{
            maxTitleNum = maxTitleLength;
        }

        if (textInputStyle) {
            inputStyles.push(textInputStyle);
        }

        if(textAlign){
            inputStyles.push({textAlign:textAlign});
        }

        if(!editable && this.state.text.length != 0){
            inputStyles.push({textAlign: textAlign ? textAlign: 'left', color: Color.input.disable});
        }

        if (showClearIcon && this.state.showClear && this.state.text.length != 0) {
            clearIconElement = (
                <TouchableHighlight
                    onPress ={()=>{
                        this._onChange('');
                    }}
                    style={imageContainerStyles}
                    underlayColor='transparent'>
                    <Image
                        source={require('../../assets/icon_textField_clear.png')}
                        style={clearImageStyles} />
                </TouchableHighlight>
            );
            inputContainerStyles.push({paddingRight:36});
        }

        if(rightImg){
            img1 = <TouchableHighlight
                style={[styles.img1Container, Platform.OS == 'harmony' &&{ zIndex:1 }]}
                underlayColor='transparent'
                onPress={() => this._iconFunc()}>
                <Image
                    style={iconStyles}
                    source={rightImg[0]}
                />
            </TouchableHighlight>;
            inputContainerStyles.push({paddingRight:50});
            if(showClearIcon){
                imageContainerStyles.push({right:52});
                inputContainerStyles.push({paddingRight:80});
            }else if(rightImg.length > 1){
                inputContainerStyles.push({paddingRight:95});
                img2 = <TouchableHighlight
                    style={[styles.img2Container, Platform.OS == 'harmony' &&{ zIndex:1 }]}
                    underlayColor='transparent'
                    onPress={() => this._iconFunc2()}>
                    <Image
                        style={iconStyles}
                        source={rightImg[1]}
                    />
                </TouchableHighlight>;
            }
        }

        if(isMerge) {
            dividerStyles.push({width: width-15, marginLeft: 15})
        }

        if(hasTopBorder) {
            if(type == 'double'){
                doubleContainerStyles.push({ borderTopWidth: 1})
            }else{
                containerStyles.push({ borderTopWidth: 1 });
            }
        }
        
        if(numberOfLines > 1){
            messageContainerStyles.push({paddingBottom: 0, paddingTop: 0});
            titleStyles.push({height: 42, marginTop: 12, alignItems: 'flex-start'});
            containerStyles.push({ minHeight: 67 });
            imageStyles.push({marginTop: 3})
            starImageStyle.push({marginTop: 6})
        }; 
          if(type == 'normal') {
            messageContainerStyles.push({width: 125})
        }

        if(this.state.showErrorInfo && this.state.errorInfo){
            errorItem =
                <View style={styles.errorInfo}>
                    <Label text={this.state.errorInfo}  labelStyle={[{color: Color.input.error, fontSize: FontSize.input.descFontSize}, errorInfoStyles]}/>
                </View>;
            containerStyles.push({minHeight: 67});
            inputContainerStyles.push({paddingBottom: 0});
        }

        if (title) {
            let tmpTitle = isLimitTitleWidth ? (title.length > maxTitleNum ? title.slice(0, maxTitleNum) : title) : title;
            let iconItem = null;
            let labelWidth = 110;
            if(titleWidth){
                titleStyles.push({width: titleWidth});
                labelWidth = titleWidth;
            }

            if(isRequired){
                labelWidth = labelWidth - 18;
            }

            if(titleIcon){
                labelWidth = labelWidth - 19;
                iconItem = <TouchableHighlight
                    onPress ={()=>{
                        this._titleIconClick();
                    }}
                    underlayColor='transparent'
                >
                    <Image
                        source={titleIcon}
                        style={[imageStyles, {marginLeft: 2}]} 
                    />
                </TouchableHighlight>
            }
            let titleFontFamily = Platform.OS==='ios'?'System' :null;
            if(titleStyle && titleStyle.fontFamily){
                titleFontFamily = titleStyle.fontFamily;
            }

            leftElement = (
                <TouchableHighlight
                    onPress ={()=>{
                        this._leftItemClick();
                    }}
                    style={messageContainerStyles}
                    underlayColor='transparent'>
                    <View style={titleStyles}>
                        <Label text={tmpTitle} numberOfLines={numberOfLines} labelStyle={{maxWidth: labelWidth, color: Color.input.title, fontSize: FontSize.input.titleFontSize, fontFamily: titleFontFamily}}/>
                        {iconItem}
                        {isRequired ? <Image
                            source={require('../../assets/textField_star.png')}
                            style={[{height: 8, width: 8, resizeMode: 'contain', marginLeft: 5, marginRight: 5}, starImageStyle]} /> : null}
                    </View>
                </TouchableHighlight>
            );
        } else if (leftIcon) {
            leftElement = (
                <TouchableHighlight
                    onPress ={()=>{
                        this._leftItemClick();
                    }}
                    style={styles.iconContainer}
                    underlayColor='transparent'>
                    <Image
                        style={iconStyles}
                        source={leftIcon}
                    />
                </TouchableHighlight>
            );
        }else{
            leftElement = type != 'double'?(
                <View style={{marginLeft:13}}></View>
            ): null;
            dividerStyles.push({height:0})
        }

        return (
            <View style={{ flex: 1 }}>
                {type == 'double' && leftElement ? (
                    <View style={doubleContainerStyles}>{leftElement}</View>
                ) : null}

                <View style={containerStyles}>
                { type !== 'double' ? leftElement : <View style={{marginLeft:13}}></View>}
                        <View style={styles.infoContainer}>
                            <View style={inputContainerStyles}>
                            {
                                Platform.OS=="ios" ?
                                <TextInput
                                    style={inputStyles}
                                    underlineColorAndroid='transparent'
                                    ref={(e) => this.textInputRefer = e}
                                    editable={editable}
                                    onChangeText={(text) => this._onChange(text)}
                                    onBlur={() => this._onBlur()}
                                    onFocus={() => this._onFocus()}
                                    placeholder={this.placeholder}
                                    placeholderTextColor={Color.input.placeholder}
                                    maxLength={maxLength}
                                    value={this.state.text}
                                    keyboardType={keyboardType}
                                    onEndEditing={()=>this._onEndEditing()}
                                    onSubmitEditing={()=>this._onSubmitEditing()}
                                    secureTextEntry={secureTextEntry}
                                    selectionColor={selectionColor}
                                />
                             : 
                                <TextInput
                                    style={[inputStyles, Platform.OS == 'harmony' ? {lineHeight: 21} : {}]}
                                    underlineColorAndroid='transparent'
                                    ref={(e) => this.textInputRefer = e}
                                    editable={editable}
                                    onChangeText={(text) => this._onChange(text)}
                                    onBlur={() => this._onBlur()}
                                    onFocus={() => this._onFocus()}
                                    placeholder={this.placeholder}
                                    placeholderTextColor={Color.input.placeholder}
                                    maxLength={maxLength}
                                    value={this.state.text}
                                    keyboardType={keyboardType}
                                    onEndEditing={()=>this._onEndEditing()}
                                    onSubmitEditing={()=>this._onSubmitEditing()}
                                    secureTextEntry={secureTextEntry}
                                />
                            }
                                {errorItem}
                            </View>
                        </View>
                    {clearIconElement}
                    {img1}
                    {img2}
                </View>
                {
                      isShowBorder && <View style={dividerStyles}/>
                    } 
            </View>
        );
    }
}

TextField.propTypes = {
    /**
     * 左侧图标
     */
    leftIcon: PropTypes.any,
    /**
     * 文字标签
     */
    title: PropTypes.string,
    /**
     * 右侧图标
     */
    showClearIcon: PropTypes.bool,
    /**
     * 用户输入时触发的方法
     */
    onChangeText: PropTypes.func,
    /**
     * 失去光标时触发的方法
     */
    onBlur: PropTypes.func,
    /**
     * 国际化
     */
    locale: PropTypes.string,
    /**
     * placeholder
     */
    placeholder: PropTypes.string,
    /**
     * 是否可编辑
     */
    editable : PropTypes.bool,
    /**
     * 输入框样式
     */
    textInputStyle : PropTypes.array,
    /**
     * 获取焦点事件
     */
    onFocus : PropTypes.func,
    /**
     * 输入框最大输入字数
     */
    maxLength:PropTypes.number,
    /**
     * 默认值
     */
    defaultValue:PropTypes.string,
    /**
     * 文字标签的最大字数
     */
    maxTitleLength:PropTypes.number,
    /**
     * 对齐方式
     */
    textAlign:PropTypes.string,
    /**
     * 右侧图标
     */
    rightImg:PropTypes.array,
    //右侧第一个图标的点击事件
    rightFunc: PropTypes.func,
    //右侧第二个图标的点击事件
    rightFunc2: PropTypes.func,
    isMerge: PropTypes.bool,
    //是否跨行合并
    hasTopBorder: PropTypes.bool,
    //是否有上边框
    showErrorInfo: PropTypes.bool,
    //是否开启错误提示
    errorInfo: PropTypes.string,
    //错误提示语
    //当前选中项与推荐选择项不符，且开启错误提示时，展示错误提示语
    //弹起键盘类型
    keyboardType: PropTypes.oneOf(['default','numeric','email-address','phone-pad']),
    //编辑完毕调用的方法
    onEndEditing: PropTypes.func,
    //软件盘的确定/提交按下时调用
    onSubmitEditing: PropTypes.func,
    //title区域宽度
    titleWidth: PropTypes.number,
    //是否显示密码遮挡样式
    secureTextEntry : PropTypes.bool,
    //标题右侧小图标
    titleIcon:PropTypes.any,
    //标题右侧小图标
    titleIconFunc:PropTypes.func,
    //是否限制标题长度
    isLimitTitleWidth:PropTypes.bool,
    //是否为必输项（显示红色*号）
    isRequired: PropTypes.bool,
    //计算内容长度方式
    calculateStyle: PropTypes.oneOf(['default','normal']),
    //设置输入框高亮时的颜色（在iOS上还包括光标）
    selectionColor:PropTypes.string,
    //设置左侧标题显示行数
    numberOfLines:PropTypes.number ,
    titleStyle: PropTypes.string,
    //是否允许重复更新defaultValue
    setDefaultValueRepeat: PropTypes.bool,
    //错误信息样式
    errorInfoStyles: PropTypes.oneOfType([PropTypes.array, PropTypes.object, PropTypes.number]),    
    //校验规则
    checker: PropTypes.string,
    //检验失败错误信息
    checkerErrMsg: PropTypes.string,
    //配置数据
    configData: PropTypes.object,
    //标题显示类型,normal,一行展示，double，标题输入框两行展示
    type: PropTypes.string,
    isShowBorder: PropTypes.bool,
    width:PropTypes.number
};

TextField.defaultProps = {
    type: 'normal',
    showClearIcon: false,
    locale: "zh",
    editable: true,
    maxLength: 50,
    maxTitleLength: 5,
    textAlign: 'left',
    isMerge: false,
    hasTopBorder: false,
    showErrorInfo:false,
    errorInfo:'',
    keyboardType:"default",
    secureTextEntry:false,
    isLimitTitleWidth:true,
    isRequired: false,
    calculateStyle:'default',
    selectionColor:'#4791ff',
    numberOfLines:1,
    setDefaultValueRepeat: false,
    checkerErrMsg:'',
    configData: {},
    isShowBorder: true,
    defaultValue: '',
};

const styles = StyleSheet.create({
    container: {
        backgroundColor: Color.white,
        minHeight: 44,
        width: Dimensions.get('window').width,
        flexDirection: 'row',
        borderColor: Color.border,
        alignItems: 'flex-start',
    },
    doubleContainer: {
        backgroundColor: Color.white,
        paddingTop: 5,
        height: 30,
        width: Dimensions.get('window').width,
        borderColor: Color.border,
        justifyContent: 'center',
    }, 
    infoContainer : {
        flex: 1,
        paddingTop: 12,
    },
    inputContainer:{
        paddingBottom: 12,
        paddingRight: 24,
        justifyContent: 'center'
    },
    input: {
        fontSize: FontSize.input.inputFontSize,
        fontFamily: Platform.OS==='ios'?'System' :'Roboto',
        fontWeight:'400',
        textAlignVertical: 'center',
        color: Color.input.input ,
        padding: 0,
        height: 21
    },
    imageContainer:{
        position:'absolute',
        right: 8,
        height: 44,
        width: 29,
        paddingTop: 8
    },
    image: {
        width: 14,  //1.8rem
        height: 14, //2rem
        zIndex: 10,
        resizeMode: 'contain'
    },
    //清除图标样式
    clearImage: {
        width: 28,  //1.8rem
        height: 28, //2rem
        zIndex: 10,
        resizeMode: 'contain'
    },
    messageContainer:{
        paddingTop: 12,
        paddingBottom: 12,
        paddingLeft: 15
    },
    title:{
        justifyContent: 'flex-start',
        height: 21,
        flexDirection: 'row',
        alignItems: 'center',
        minWidth: 110
    },
    iconContainer:{
        width: 125,
        paddingLeft: 15,
        justifyContent: 'center',
    },
    icon : {
        width: 28,
        height: 28,
        resizeMode:'contain',
        marginTop: 8
    },
    img1Container : {
        position:'absolute',
        right: 8
    },
    img2Container : {
        position:'absolute',
        right: 48
    },
    divider:{
        width: Dimensions.get('window').width,
        height: 1,
        backgroundColor: Color.border,
    },
    errorInfo:{
        justifyContent: 'center',
        marginBottom:12,
        marginTop : 5
    }
});
